/**********************************************************
* @ File name -> button.cpp
* @ Version   -> V1.0
* @ Date      -> 20160715
* @ Brief     -> 急停按钮
**********************************************************/

#include "mod_port.h"
#include "platform.h"
#include "port.h"

#include <assert.h>

#define DRV_BUTTON_STATE_DOWN (0U)
#define DRV_BUTTON_STATE_UP   (1U)

/* 端口状态结构体 */
struct PortState {
    uint8_t state;    /* 按键状态 */
    uint8_t stateTmp; /* 临时状态 */
    uint8_t open_cnt;
    uint8_t close_cnt;  
    uint8_t open_cnt_max;
    uint8_t close_cnt_max;    
    uint8_t (*read_pin_state)(void); /*读取端口状态函数 */ 
};

static struct PortState state[PORT_STATE_MAX]={
    {DRV_BUTTON_STATE_UP, DRV_BUTTON_STATE_UP, 0, 0, 4, 4, estop_read_state},
    {DRV_BUTTON_STATE_UP, DRV_BUTTON_STATE_UP, 0, 0, 40, 5, relay_read_l_state},
    {DRV_BUTTON_STATE_UP, DRV_BUTTON_STATE_UP, 0, 0, 40, 5, relay_read_n_state},
    {DRV_BUTTON_STATE_UP, DRV_BUTTON_STATE_UP, 0, 0, 4, 4, cc_read_state},
};

static void port_poll(void){
    uint32_t i;
    for (i=0U; i<PORT_STATE_MAX; i++){
        if (state[i].read_pin_state != NULL){
            uint8_t tmp = state[i].read_pin_state();
            if (tmp == DRV_BUTTON_STATE_UP){
                if ((i != PORT_STATE_RELAY_L) && (i != PORT_STATE_RELAY_N)){
                    state[i].close_cnt = 0;
                }                   

                state[i].open_cnt++;
                if (state[i].open_cnt > state[i].open_cnt_max){
                    state[i].stateTmp = tmp;
                    state[i].open_cnt = 0;
                    state[i].close_cnt = 0;
                }
            }else{
                state[i].open_cnt = 0;
                state[i].close_cnt++;
                if (state[i].close_cnt > state[i].close_cnt_max){
                    state[i].stateTmp = tmp;
                    state[i].close_cnt = 0;
                }
            }

            if (state[i].state != state[i].stateTmp){
                state[i].state = state[i].stateTmp;
                printf("port %d state:%s\r\n", i, (state[i].state == DRV_BUTTON_STATE_DOWN) ? "close" : "open");
            }
        }
    }
}

static void port_task(void *para) {
    para = para;
    
    /*lint -e(716) */
    while(1){
        port_poll();
        os_msleep(3U);
    }
}

int32_t port_init(void) {
    int32_t ret = 0;
    os_pthread_t port_thread;
    estop_port_init();
    relay_check_port_init();
    cc_port_init();
    
    if (os_pthread_create("port", &port_thread, port_task, NULL, OS_TASK_PRIO_LOW,  OS_STACK_SIZE_LITTLE) != 0){
        ret = -1;
    }
    
    return ret;
}

uint8_t port_get_state(uint32_t pos){
    assert(pos < PORT_STATE_MAX);
    return state[pos].state;
}

int32_t port_is_close(uint32_t pos) {
    return (state[pos].state == DRV_BUTTON_STATE_DOWN);
}

void port_light_open(void){

}

void port_light_close(void){

}



